package visualization;

import graphs.OdorSparsnessHeatJGraph;

import java.util.ArrayList;

import javax.swing.JComboBox;
import javax.swing.JSpinner;
import javax.swing.event.ChangeEvent;
import javax.swing.JOptionPane;
import javax.swing.event.ChangeListener;

import odor.Odor;


import structures.Network;
import util.Util;

/*
 * OptionsFrame.java
 *
 * Created on Jul 13, 2011, 2:07:29 PM
 */

/**
 *
 * @author pedro
 */
public class OptionsFrame extends javax.swing.JFrame 
{
	private static final long serialVersionUID = 6481031491918427239L;
	private ArrayList<JNetwork> networks;
	private Odor[] battery;
	private boolean lockedNetworkComboBox = false;
	
	public OptionsFrame(ArrayList<JNetwork> networks)
	{
		this.networks = networks;
		initComponents();
	}
	
	public OptionsFrame(ArrayList<JNetwork> networks, Odor[] battery)
	{
		this.networks = networks;
		this.battery = battery;
		initComponents();
	}
	
    /** Creates new form OptionsFrame */
    public OptionsFrame() 
    {
        initComponents();
    }
    
    private class SpinnerValueChangeListener implements ChangeListener
    {
		public void stateChanged(ChangeEvent arg0) 
		{
			JSpinner spn = (JSpinner) arg0.getSource();
			double i = 0;
			
			try
			{
				Double d = (Double)(spn.getValue());
				i = d;
			}catch(Exception e) {}
			
			try
			{
				Integer I = (Integer)(spn.getValue());
				i = I;
			}catch(Exception e) {}
			
			if (i < 0.00)
			{
				spn.setValue(0);
				return;
			}
			else
			{
				return;
			}
		}
    }
    
    private void updateOdorPanel()
    {
    	if (battery != null)
    	{
	    	OdorBatteryNumSpinner.setValue(battery.length);
	    	
	    	double[] batteryStdevs = new double[battery.length];
	    	for (int x=0; x<battery.length; x++)
	    	{
	    		batteryStdevs[x] = battery[x].getStandardDeviation();
	    	}
	    	double averageSTDev = Util.arraySum(batteryStdevs)/(battery.length);
	    	
	    	
	    	OdorBatterySTDevSpinner.setValue(averageSTDev);
	    	validate();
    	}
    }
    
    @Deprecated
    private void updateInfoPanel(JNetwork n)
    {
    	/*
    	GTMWeightsMeanSpinner.setValue(n.getGTMWeightMean());
    	GTMWeightsSTDevSpinner.setValue(n.getGTMWeightSTDev());
    	MTGConnectivityMeanSpinner.setValue(n.getMTGConnectivityMean());
    	MTGConnectivitySTDevSpinner.setValue(n.getMTGConnectivitySTDev());
    	MTGWeightsMeanSpinner.setValue(n.getMTGWeightMean());
    	MTGWeightsSTDevSpinner.setValue(n.getMTGWeightSTDev());
    	GranuleThresholdMeanSpinner.setValue(n.getGranuleThresholdMean());
    	GranuleThresholdSTDevSpinner.setValue(n.getGranuleThresholdSTDev());
    	*/
    }
    
    private class STDevSpinnerValueChangeListener implements ChangeListener
    {
    	private JSpinner checkAgainst;
    	
    	public STDevSpinnerValueChangeListener(JSpinner checkAgainst)
    	{
    		super();
    		this.checkAgainst = checkAgainst;
    	}
    	
    	//@Override
    	public void stateChanged(ChangeEvent arg0) 
		{
			JSpinner spn = (JSpinner) arg0.getSource();
			
			double currValue = 0, check = 0;
			
			try
			{
				currValue = (Integer)(spn.getValue());
				check = (Integer)(checkAgainst.getValue());
			}catch(Exception e) {}
			
			try
			{
				currValue = (Double)(spn.getValue());
				check = (Double)(checkAgainst.getValue());
			}catch(Exception e) {}
			
			if (currValue < 0.00)
			{
				spn.setValue(0);
				return;
			}
			else if (currValue > check)
			{
				spn.setValue((check > 0)? (check-1):(0));
			}
			else
			{
				return;
			}
		}
    }
    
    private void addJSpinnerChangeListeners()
    {
    	SpinnerValueChangeListener spinnerValueChangeListener = new SpinnerValueChangeListener();
    	
		GTMWeightsMeanSpinner.addChangeListener(spinnerValueChangeListener);
		GTMWeightsSTDevSpinner.addChangeListener(spinnerValueChangeListener);
        
        MTGConnectivityMeanSpinner.addChangeListener(spinnerValueChangeListener);
        MTGConnectivitySTDevSpinner.addChangeListener(spinnerValueChangeListener);
        
        MTGWeightsMeanSpinner.addChangeListener(spinnerValueChangeListener);
        MTGWeightsSTDevSpinner.addChangeListener(spinnerValueChangeListener);
        
        GranuleThresholdMeanSpinner.addChangeListener(spinnerValueChangeListener);
        GranuleThresholdSTDevSpinner.addChangeListener(spinnerValueChangeListener);
        
        OdorBatterySTDevSpinner.addChangeListener(spinnerValueChangeListener);
        
        OdorBatteryNumSpinner.addChangeListener(spinnerValueChangeListener);
        
        NumNetworksSpinner.addChangeListener(new ChangeListener(){

			public void stateChanged(ChangeEvent e) 
			{
				if (isVisible() == false)
					return;
				
				JSpinner src = (JSpinner)e.getSource();
				JNetwork selected = (JNetwork) EditNetworksComboBox.getItemAt(EditNetworksComboBox.getSelectedIndex());
				int value = (Integer)(src.getValue());
				
				if (value  <= 0)
				{
					//Case 1: Remove all but selected
					lockedNetworkComboBox = true;
					
					networks.clear();
					EditNetworksComboBox.removeAllItems();
					networks.add(selected);
					
					lockedNetworkComboBox = false;
					
					EditNetworksComboBox.addItem(selected);
					
					src.setValue(new Integer(1));
				}
				else if (value < EditNetworksComboBox.getItemCount())
				{
					//Remove until equals value, don't remove selected
					
					int counter  = 0;
					while(value < EditNetworksComboBox.getItemCount())
					{
						JNetwork next = (JNetwork) EditNetworksComboBox.getItemAt(counter);
						
						if (next == null)
						{
							counter = 0;
							continue;
						}
						
						if (next.toString().compareTo(selected.toString()) != 0)
						{
							EditNetworksComboBox.removeItemAt(counter);
						}
						
						counter++;
					}
				}
				else if(value > EditNetworksComboBox.getItemCount())
				{
					while (value != EditNetworksComboBox.getItemCount())
					{
						JNetwork curr = new JNetwork(new Network(main.Main.NUM_COLS));
						networks.add(curr);
						EditNetworksComboBox.addItem(curr);
					}
				}
			}
        	
        });
    }
   
    /** This method is called from within the constructor to
     * initialize the form.
     */
    private void initComponents() 
    {
    	setLocation(20,20);
    	
        OptionsLabel = new javax.swing.JLabel();
        NumNetworksSpinner = new javax.swing.JSpinner();
        NumNetworksLabel = new javax.swing.JLabel();
        EditNetworksComboBox = new javax.swing.JComboBox();
        NetworkEditorPanel = new javax.swing.JPanel();
        GranuleThresholdLabel = new javax.swing.JLabel();
        GranuleThresholdMeanSpinner = new javax.swing.JSpinner();
        GranuleThresholdMeanLabel = new javax.swing.JLabel();
        GranuleThresholdSTDevLabel = new javax.swing.JLabel();
        GranuleThresholdSTDevSpinner = new javax.swing.JSpinner();
        MTGConnectivityLabel = new javax.swing.JLabel();
        MTGConnectivityMeanSpinner = new javax.swing.JSpinner();
        NetworkEditorApplyChangesButton = new javax.swing.JButton();
        MTGConnectivityMeanLabel = new javax.swing.JLabel();
        MTGConnectivitySTDevLabel = new javax.swing.JLabel();
        MTGConnectivitySTDevSpinner = new javax.swing.JSpinner();
        MTGWeightsLabel = new javax.swing.JLabel();
        MTGWeightsMeanLabel = new javax.swing.JLabel();
        MTGWeightsMeanSpinner = new javax.swing.JSpinner();
        MTGWeightsSTDevLabel = new javax.swing.JLabel();
        MTGWeightsSTDevSpinner = new javax.swing.JSpinner();
        GTMWeightsLabel = new javax.swing.JLabel();
        GTMWeightsMeanLabel = new javax.swing.JLabel();
        GTMWeightsMeanSpinner = new javax.swing.JSpinner();
        GTMWeightsSTDevLabel = new javax.swing.JLabel();
        GTMWeightsSTDevSpinner = new javax.swing.JSpinner();
        NetworkEditorLabel = new javax.swing.JLabel();
        OdorBatteryLabel = new javax.swing.JLabel();
        GenerateOdorBatteryButton = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JSeparator();
        jSeparator2 = new javax.swing.JSeparator();
        OdorBatteryNumLabel = new javax.swing.JLabel();
        OdorBatteryNumSpinner = new javax.swing.JSpinner();
        OdorBatterySTDevLabel = new javax.swing.JLabel();
        OdorBatterySTDevSpinner = new javax.swing.JSpinner();
        CurrentOdorHeatGraphButton = new javax.swing.JButton();
        PreviewOdorHeatGraphButton = new javax.swing.JButton();
        EditNetworkLabel = new javax.swing.JLabel();
        
        setDefaultCloseOperation(javax.swing.WindowConstants.HIDE_ON_CLOSE);
        setTitle("Options");
        
        OptionsLabel.setFont(new java.awt.Font("DejaVu LGC Sans", 1, 14)); // NOI18N
        OptionsLabel.setText("OPTIONS");
        
        NumNetworksLabel.setText("# Networks Used:");
        
        EditNetworksComboBox.addActionListener(new java.awt.event.ActionListener() 
        {
            public void actionPerformed(java.awt.event.ActionEvent evt) 
            {
            	if (lockedNetworkComboBox == true)
            		return;
            	
            	JNetwork selectedNetwork = (JNetwork)(((JComboBox) evt.getSource()).getSelectedItem());
            	updateInfoPanel(selectedNetwork);
            }
        });

        NetworkEditorPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        GranuleThresholdLabel.setFont(new java.awt.Font("DejaVu LGC Sans", 1, 12)); // NOI18N
        GranuleThresholdLabel.setText("Theta (Avg G Threshold):");

        GranuleThresholdMeanLabel.setText("Mean:");

        GranuleThresholdSTDevLabel.setText("STDev:");

        MTGConnectivityLabel.setFont(new java.awt.Font("DejaVu LGC Sans", 1, 12)); // NOI18N
        MTGConnectivityLabel.setText("Mitral-to-Granule Connectivity:");

        NetworkEditorApplyChangesButton.setFont(new java.awt.Font("DejaVu LGC Sans", 1, 13)); // NOI18N
        NetworkEditorApplyChangesButton.setText("APPLY CHANGES");
        NetworkEditorApplyChangesButton.addActionListener(new java.awt.event.ActionListener() 
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                NetworkEditorApplyChangesButtonActionPerformed(evt);
            }
        });

        MTGConnectivityMeanLabel.setText("Mean:");

        MTGConnectivitySTDevLabel.setText("STDev:");

        MTGWeightsLabel.setFont(new java.awt.Font("DejaVu LGC Sans", 1, 12)); // NOI18N
        MTGWeightsLabel.setText("Mitral-to-Granule Weights:");

        MTGWeightsMeanLabel.setText("Mean:");

        MTGWeightsSTDevLabel.setText("STDev:");

        GTMWeightsLabel.setFont(new java.awt.Font("DejaVu LGC Sans", 1, 12)); // NOI18N
        GTMWeightsLabel.setText("Granule-to-Mitral Weights:");

        GTMWeightsMeanLabel.setText("Mean:");

        GTMWeightsSTDevLabel.setText("STDev:");
        
        javax.swing.GroupLayout NetworkEditorPanelLayout = new javax.swing.GroupLayout(NetworkEditorPanel);
        NetworkEditorPanel.setLayout(NetworkEditorPanelLayout);
        NetworkEditorPanelLayout.setHorizontalGroup(
            NetworkEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, NetworkEditorPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(NetworkEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(NetworkEditorApplyChangesButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE)
                    .addComponent(GranuleThresholdLabel, javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, NetworkEditorPanelLayout.createSequentialGroup()
                        .addComponent(MTGConnectivityMeanLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(MTGConnectivityMeanSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(MTGConnectivitySTDevLabel)
                        .addGap(18, 18, 18)
                        .addComponent(MTGConnectivitySTDevSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, 53, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, NetworkEditorPanelLayout.createSequentialGroup()
                        .addComponent(GranuleThresholdMeanLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(GranuleThresholdMeanSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(GranuleThresholdSTDevLabel)
                        .addGap(18, 18, 18)
                        .addComponent(GranuleThresholdSTDevSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, 55, Short.MAX_VALUE))
                    .addComponent(MTGConnectivityLabel, javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(MTGWeightsLabel, javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, NetworkEditorPanelLayout.createSequentialGroup()
                        .addComponent(MTGWeightsMeanLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(MTGWeightsMeanSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(MTGWeightsSTDevLabel)
                        .addGap(18, 18, 18)
                        .addComponent(MTGWeightsSTDevSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, 53, Short.MAX_VALUE))
                    .addComponent(GTMWeightsLabel, javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, NetworkEditorPanelLayout.createSequentialGroup()
                        .addComponent(GTMWeightsMeanLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(GTMWeightsMeanSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(GTMWeightsSTDevLabel)
                        .addGap(18, 18, 18)
                        .addComponent(GTMWeightsSTDevSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, 53, Short.MAX_VALUE)))
                .addContainerGap())
        );
        NetworkEditorPanelLayout.setVerticalGroup(
            NetworkEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(NetworkEditorPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(GranuleThresholdLabel)
                .addGap(8, 8, 8)
                .addGroup(NetworkEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(GranuleThresholdMeanSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(GranuleThresholdSTDevSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(GranuleThresholdMeanLabel)
                    .addComponent(GranuleThresholdSTDevLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(MTGConnectivityLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(NetworkEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(MTGConnectivityMeanLabel)
                    .addComponent(MTGConnectivityMeanSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(MTGConnectivitySTDevLabel)
                    .addComponent(MTGConnectivitySTDevSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(MTGWeightsLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(NetworkEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(MTGWeightsMeanLabel)
                    .addComponent(MTGWeightsMeanSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(MTGWeightsSTDevLabel)
                    .addComponent(MTGWeightsSTDevSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(GTMWeightsLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(NetworkEditorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(GTMWeightsMeanLabel)
                    .addComponent(GTMWeightsMeanSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(GTMWeightsSTDevLabel)
                    .addComponent(GTMWeightsSTDevSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(NetworkEditorApplyChangesButton, javax.swing.GroupLayout.DEFAULT_SIZE, 59, Short.MAX_VALUE))
        );

        NetworkEditorLabel.setFont(new java.awt.Font("DejaVu LGC Sans", 1, 14)); // NOI18N
        NetworkEditorLabel.setText("NETWORK EDITOR");

        OdorBatteryLabel.setFont(new java.awt.Font("DejaVu LGC Sans", 1, 12)); // NOI18N
        OdorBatteryLabel.setText("Odor Battery:");

        GenerateOdorBatteryButton.setFont(new java.awt.Font("DejaVu LGC Sans", 1, 13)); // NOI18N
        GenerateOdorBatteryButton.setText("Generate");
        GenerateOdorBatteryButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                GenerateOdorBatteryButtonActionPerformed(evt);
            }
        });
        GenerateOdorBatteryButton.setToolTipText("Generate New Odor Battery");

        OdorBatteryNumLabel.setText("Num Odors:");

        OdorBatterySTDevLabel.setText("Avg. STDev:");

        CurrentOdorHeatGraphButton.setText("Curr HGraph");
        CurrentOdorHeatGraphButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CurrentOdorHeatGraphButtonActionPerformed(evt);
            }
        });

        PreviewOdorHeatGraphButton.setText("Prvw HGraph");
        PreviewOdorHeatGraphButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PreviewOdorHeatGraphButtonActionPerformed(evt);
            }
        });

        EditNetworkLabel.setText("Edit Network:");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(OptionsLabel))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(NetworkEditorLabel))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(NetworkEditorPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 294, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(EditNetworkLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 115, Short.MAX_VALUE)
                            .addComponent(NumNetworksLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(58, 58, 58)
                                .addComponent(NumNetworksSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, 109, Short.MAX_VALUE))
                            .addGroup(layout.createSequentialGroup()
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(EditNetworksComboBox, 0, 155, Short.MAX_VALUE)))))
                .addContainerGap())
            .addComponent(jSeparator2, javax.swing.GroupLayout.DEFAULT_SIZE, 306, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(CurrentOdorHeatGraphButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(PreviewOdorHeatGraphButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(GenerateOdorBatteryButton, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(OdorBatteryNumLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(OdorBatteryNumSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(OdorBatterySTDevLabel)
                .addGap(18, 18, 18)
                .addComponent(OdorBatterySTDevSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, 67, Short.MAX_VALUE)
                .addGap(28, 28, 28))
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(OdorBatteryLabel)
                .addContainerGap(197, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(OptionsLabel)
                .addGap(1, 1, 1)
                .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(3, 3, 3)
                .addComponent(OdorBatteryLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(OdorBatteryNumSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(OdorBatterySTDevSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(OdorBatteryNumLabel)
                    .addComponent(OdorBatterySTDevLabel))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(GenerateOdorBatteryButton, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(CurrentOdorHeatGraphButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(PreviewOdorHeatGraphButton, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(NetworkEditorLabel)
                .addGap(13, 13, 13)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(NumNetworksLabel)
                    .addComponent(NumNetworksSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(EditNetworksComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(EditNetworkLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(NetworkEditorPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        
        addJSpinnerChangeListeners();
        populateJNetworks();
        updateOdorPanel();
        
        pack();
    }

    private void populateJNetworks() 
    {
		if (this.networks != null && this.networks.isEmpty() == false)
		{
			this.NumNetworksSpinner.setValue(this.networks.size());
			for (JNetwork n : this.networks)
			{
				this.EditNetworksComboBox.addItem(n);
			}
		}
	}

	private void CurrentOdorHeatGraphButtonActionPerformed(java.awt.event.ActionEvent evt) 
    {
		if(battery != null)
		{
			OdorSparsnessHeatJGraph g = new OdorSparsnessHeatJGraph(battery);
			g.setTitle("Current Odor Battery");
		}
		else
		{
			JOptionPane.showMessageDialog(this, "No Battery Available");
		}
    }

    private void PreviewOdorHeatGraphButtonActionPerformed(java.awt.event.ActionEvent evt) 
    {
        Odor[] tempBattery = Odor.generateOdorBattery(
        		(Integer)(OdorBatteryNumSpinner.getValue()), 
        		main.Main.NUM_COLS, 
        		main.Main.ODOR_INPUT_SUM, 
        		Util.attemptValueCast(OdorBatterySTDevSpinner.getValue()));
        
        OdorSparsnessHeatJGraph g = new OdorSparsnessHeatJGraph(tempBattery);
        g.setTitle("Previewed Odor Battery");
    }

    private void GenerateOdorBatteryButtonActionPerformed(java.awt.event.ActionEvent evt) 
    {
        battery = Odor.generateOdorBattery(
        		(Integer)(OdorBatteryNumSpinner.getValue()), 
        		main.Main.NUM_COLS, 
        		main.Main.ODOR_INPUT_SUM, 
        		Util.attemptValueCast(OdorBatterySTDevSpinner.getValue()));
        updateOdorPanel();
        repaint();
    }

    @Deprecated
    private void NetworkEditorApplyChangesButtonActionPerformed(java.awt.event.ActionEvent evt) 
    {
        /*
    	Network n = new Network(main.Main.NUM_COLS, 
        		Util.attemptValueCast(this.GranuleThresholdMeanSpinner.getValue()),
        		Util.attemptValueCast(this.GranuleThresholdSTDevSpinner.getValue()), 
        		Util.attemptValueCast(this.MTGWeightsMeanSpinner.getValue()), 
        		Util.attemptValueCast(this.MTGWeightsSTDevSpinner.getValue()),
        		Util.attemptValueCast(this.MTGConnectivityMeanSpinner.getValue()), 
        		Util.attemptValueCast(this.MTGConnectivitySTDevSpinner.getValue()), 
        		Util.attemptValueCast(this.GTMWeightsMeanSpinner.getValue()), 
        		Util.attemptValueCast(this.GTMWeightsSTDevSpinner.getValue()));
        
        double id = ((JNetwork)(this.EditNetworksComboBox.getSelectedItem())).getID();
        
        this.networks.remove(this.EditNetworksComboBox.getSelectedIndex());
        this.EditNetworksComboBox.removeItemAt(this.EditNetworksComboBox.getSelectedIndex());
        
        JNetwork newNetwork = new JNetwork(n);
        newNetwork.setID(id);
        
        this.networks.add(newNetwork);
        this.EditNetworksComboBox.addItem(newNetwork);
        this.EditNetworksComboBox.setSelectedItem(newNetwork);
        */
    }
    
    
    private javax.swing.JButton CurrentOdorHeatGraphButton;
    private javax.swing.JButton GenerateOdorBatteryButton;
    private javax.swing.JButton NetworkEditorApplyChangesButton;
    private javax.swing.JButton PreviewOdorHeatGraphButton;
    
    private javax.swing.JComboBox EditNetworksComboBox;
    
    private javax.swing.JLabel EditNetworkLabel;
    private javax.swing.JLabel GTMWeightsLabel;
    private javax.swing.JLabel GTMWeightsMeanLabel;
    private javax.swing.JLabel GTMWeightsSTDevLabel;
    private javax.swing.JLabel MTGConnectivityLabel;
    private javax.swing.JLabel MTGConnectivityMeanLabel;
    private javax.swing.JLabel MTGConnectivitySTDevLabel;
    private javax.swing.JLabel MTGWeightsLabel;
    private javax.swing.JLabel MTGWeightsMeanLabel;
    private javax.swing.JLabel MTGWeightsSTDevLabel;
    private javax.swing.JLabel NetworkEditorLabel;
    private javax.swing.JLabel NumNetworksLabel;
    private javax.swing.JLabel OdorBatteryLabel;
    private javax.swing.JLabel OdorBatteryNumLabel;
    private javax.swing.JLabel OdorBatterySTDevLabel;
    private javax.swing.JLabel OptionsLabel;
    private javax.swing.JLabel GranuleThresholdLabel;
    private javax.swing.JLabel GranuleThresholdMeanLabel;
    private javax.swing.JLabel GranuleThresholdSTDevLabel;
    
    private javax.swing.JPanel NetworkEditorPanel;
    
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    
    private javax.swing.JSpinner GTMWeightsMeanSpinner;
    private javax.swing.JSpinner GTMWeightsSTDevSpinner;
    private javax.swing.JSpinner MTGConnectivityMeanSpinner;
    private javax.swing.JSpinner MTGConnectivitySTDevSpinner;
    private javax.swing.JSpinner MTGWeightsMeanSpinner;
    private javax.swing.JSpinner MTGWeightsSTDevSpinner;
    private javax.swing.JSpinner NumNetworksSpinner;
    private javax.swing.JSpinner OdorBatteryNumSpinner;
    private javax.swing.JSpinner OdorBatterySTDevSpinner;
    private javax.swing.JSpinner GranuleThresholdMeanSpinner;
    private javax.swing.JSpinner GranuleThresholdSTDevSpinner;
}

